import numpy as np
import pandas as pd
from datetime import *
import matplotlib.pyplot as plt
import math
import os

# 读取要操作的csv表格，遍历持仓表中进行操作的品种后，读取所需品种的价位表进行操作（合并表格）
#可以看到持仓表数据为2787，价位表数据不一，有几万条，但是采取当日最后一分钟价格整理后，表格长度应一致
print('请输入持仓表：')
targetName = input()
#判断仓位是按比例还是数额决定是否要统一格式
if targetName == "SampleTarget1.csv":
    divisor = 1000000
else:
    divisor = 1
st = pd.read_csv("D:\PKU\python\homework\Final"+'/' + targetName)
root = 'D:\PKU\python\homework\Final\data'
#删除全空列后获取列名即需要用到的产品价格表
st = st.dropna(how="all", axis=1)
st.fillna(0)
# print(st)
result=pd.DataFrame()
file_names = list(st.iloc[:,2:].columns)
# print(file_names)

#对用到的产品p进行遍历读取，表格进行处理后合并出以’trading_day‘为索引，产品_clz，st_产品，产品价格、手续费、turnover等为表头的表格。
for file_name in file_names:
    fileob = root + '/' + file_name + '.ft'
    # p_clz_name = file_name + '_clz'
    p = pd.read_feather(fileob)
    p_clz = p.loc[:,['trading_day','timestamp','clz']]
    st_p = st.loc[:,['trading_day','timestamp',file_name]]
    #对仓位统一格式
    st_p[file_name] = st_p[file_name] / divisor
    #合并持仓和价位表
    p_clz_stt = pd.merge(st_p, p_clz, on=['trading_day', 'timestamp'], how='left')
    p_clz_st = p_clz_stt.set_index('trading_day')



# 计算需要的数据，市价、手续费、换手率等,对表格进行扩充后并表

    #命名段start
    position_tab = "position_" + file_name #目标仓位
    num_tab = "num_" +file_name
    clz_tab = "clz_" + file_name #产品clz
    st_tab = "st_" + file_name  #产品持仓
    value_tab = "value_" + file_name    #产品市价
    com_tab = "com_" + file_name    #产品手续费
    turnover_tab = "turnover_" + file_name  #产品换手
    pnl_tab = "pnl_" + file_name    #产品损益
    pnlnet_tab = "pnlnet_" + file_name  #产品费后损益
    p_clz_st.rename(columns={"clz":clz_tab},inplace=True) #把当前产品的clz字段重命名为clz_产品
    p_clz_st.rename(columns={file_name:st_tab}, inplace=True)
    #命名段finish
    #相关指标计算start
    p_clz_st.loc[(p_clz_st[st_tab] != 0) & (p_clz_st[clz_tab] != p_clz_st[clz_tab]), st_tab] = 0
    p_clz_st[num_tab] = p_clz_st[st_tab]/p_clz_st[clz_tab]
    p_clz_st[value_tab] = -(p_clz_st[num_tab] - p_clz_st[num_tab].shift(periods=1, axis=0)) * p_clz_st[clz_tab]
    p_clz_st[com_tab] = abs(p_clz_st[value_tab]) * 0.0003
    p_clz_st[turnover_tab] = -1 * p_clz_st[value_tab]
    p_clz_st[pnl_tab]= p_clz_st[num_tab].shift(1) * p_clz_st[clz_tab].diff()
    p_clz_st[pnlnet_tab] = p_clz_st[pnl_tab] - p_clz_st[com_tab]

    #相关指标计算finish
    #累计并表start
    result = pd.concat([result, p_clz_st], axis=1)
    #累积并表finish


print(result)
#targetname = targetName + 'result.csv'
# result.to_csv (targetname, mode="a" ,header=True, index=True,encoding='gb18030')
#对合并后的大表进行操作，计算累积pnl，pnlnet等数据
result.fillna(0,inplace=True)
pnl_names = []
pnlnet_names = []
turnover_names=[]
st_names=[]
for file_name in file_names:
    pnl_tab = "pnl_" + file_name
    pnlnet_tab = "pnlnet_" + file_name
    turnover_tab = "turnover_" + file_name
    st_tab = "st_" + file_name
    st_names.append(st_tab)
    pnl_names.append(pnl_tab)
    pnlnet_names.append(pnlnet_tab)
    turnover_names.append(turnover_tab)
result['total_pnl'] = result.loc[:, pnl_names].apply(lambda x:x.sum(),axis=1).cumsum()
result['total_pnlnet'] = result.loc[:, pnlnet_names].apply(lambda x:x.sum(),axis=1)
result['pnlnet'] = result['total_pnlnet'].cumsum()
result['sharp'] = np.mean(result['total_pnlnet'])/np.std(result['total_pnlnet'])*15.8
SharpRatio = result.iloc[-1]['sharp']
# result[turnover_tab] = result[turnover_tab]
result['Turnover'] = result.loc[:, turnover_names].apply(lambda x:x.sum(), axis=1)
result['total_turnover']=result['Turnover'].sum()/(result['Turnover']!=np.nan).sum()
TurnOver = result.iloc[-1]['total_turnover']
result['AvgLeverage'] = result.loc[:, st_names].apply(lambda x:x.sum(), axis=1)
AvgLeverage = result.iloc[-1]['AvgLeverage']
print(result)

#绘制图表
result['date'] = result.index.values
x = result['date'].apply(lambda x:datetime.strptime(str(x),'%Y%m%d'))
y = result['total_pnl']
z = result['pnlnet']

plt.figure(figsize=(10,5))
plt.grid()
plt.title('SharpRatio='+str(round(SharpRatio, 4)) + ' , Turnover=' + str(round(TurnOver, 4)) + ' , AvgLeverage=' + str(round(AvgLeverage, 4)))
#x-y线
plt.plot(x,y,color='red', label='total_pnl')
plt.legend()
#x-z线
plt.plot(x,z,color='blue', label='total_pnlnet')
plt.legend()

plt.xlabel('date')
plt.show()


